package top.zywork.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import top.zywork.annotation.SysLog;
import top.zywork.common.*;
import top.zywork.constant.CommonConstant;
import top.zywork.constant.FileConstants;
import top.zywork.dto.GraphicOrderDTO;
import top.zywork.dto.PagerDTO;
import top.zywork.enums.DatePatternEnum;
import top.zywork.enums.PayStatusEnum;
import top.zywork.enums.UploadTypeEnum;
import top.zywork.enums.UploadTypeEnums;
import top.zywork.ext.dos.GraphicExtDO;
import top.zywork.ext.dos.GraphicOrderExtDO;
import top.zywork.ext.service.GraphicExtService;
import top.zywork.ext.service.GraphicOrderExtService;
import top.zywork.query.GraphicOrderQuery;
import top.zywork.security.SecurityUtils;
import top.zywork.service.GraphicOrderService;
import top.zywork.service.UploadService;
import top.zywork.vo.GraphicOrderVO;
import top.zywork.vo.PagerVO;
import top.zywork.vo.ResponseStatusVO;
import top.zywork.wx.save.GraphicOrderSave;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * GraphicOrderController控制器类<br/>
 *
 * 创建于2020-11-28<br/>
 *
 * @author http://ljyanimo.com 刘金泳
 * @version 1.0
 */
@RestController
@RequestMapping("/graphic-order")
@Slf4j
public class GraphicOrderController extends BaseController {

    private GraphicOrderService graphicOrderService;

    @Value("${storage.provider}")
    private String storageProvider;

    @Value("${storage.local.compressSizes}")
    private String compressSizes;

    @Value("${storage.local.compressScales}")
    private String compressScales;

    @Value("${storage.local.graphicOrder.imgParentDir}")
    private String imgParentDir;

    @Value("${storage.local.graphicOrder.imgDir}")
    private String imgDir;

    @Value("${storage.local.graphicOrder.imgUrl}")
    private String imgUrl;

    @Value("${storage.local.graphicOrder.keepFileName}")
    private Boolean keepFileName;

    @Autowired
    private UploadService uploadService;


    @Autowired
    private GraphicOrderExtService graphicOrderExtService;

    @Autowired
    private GraphicExtService graphicExtService;

    /**
     * 用户word打印下单
     * @param bindingResult
     * @return
     */
    @PostMapping("user/place")
    public ResponseStatusVO place(@RequestBody @Validated GraphicOrderSave graphicOrderSave, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        return graphicOrderService.placeOrder(graphicOrderSave);
    }

    /**
     * 用户当前订单
     * @return
     */
    @PostMapping("user/orderList")
    public ResponseStatusVO orderList(@RequestBody @Validated top.zywork.wx.query.GraphicOrderQuery graphicOrderQuery, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        long userId = SecurityUtils.getJwtUser().getUserId();
        Page page = new Page(graphicOrderQuery.getPageNo(),graphicOrderQuery.getPageSize());
        QueryWrapper<GraphicOrderExtDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("is_active", CommonConstant.IS_ACTIVE_TRUE);
        IPage ipage = graphicOrderExtService.page(page, queryWrapper);
        return ResponseStatusVO.ok("查询成功",ipage);
    }

    /**
     * @param file
     * @return
     */
    @PostMapping("user/upload-word")
    @SysLog(description = "后台上传文档", requestParams = false)
    public ResponseStatusVO uploadHeadicon(MultipartFile file) {
        String date = DateFormatUtils.format(DateUtils.currentDate(), DatePatternEnum.DATE.getValue());
        UploadUtils.UploadOptions uploadOptions = UploadUtils.UploadOptions.builder().uploadParentDir(imgParentDir).uploadDir(imgDir + FileConstants.SEPARATOR + date)
                .dbSaveUrl(imgUrl + FileConstants.SEPARATOR + date).keepFileName(keepFileName).build();



        ResponseStatusVO responseStatusVO = uploadService.uploadFile(storageProvider, file, UploadTypeEnums.IMAGEANDOFFICE.getAllowedExts(), UploadTypeEnums.IMAGEANDOFFICE.getMaxSize(), uploadOptions);

        return responseStatusVO;
    }

    @GetMapping("admin/updateDyStatus/{id}")
    public ResponseStatusVO updateDyStatus(@PathVariable("id") Integer id){
        GraphicOrderExtDO orderExtDO = graphicOrderExtService.getById(id);
        if(orderExtDO != null){
            orderExtDO.setCompletionStatus("已打印");
            graphicOrderExtService.updateById(orderExtDO);
            return ResponseStatusVO.ok("修改成功",null);
        }
        return ResponseStatusVO.error("错误",null);
    }

    @PostMapping("any/zip/{id}")
    public void zip(@PathVariable("id") Integer id, HttpServletResponse response){
        GraphicOrderExtDO graphicOrderExtDO = graphicOrderExtService.getById(id);
        String[] fileUrl = graphicOrderExtDO.getUploadFile().split(",");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + new String( (graphicOrderExtDO.getTakeCode() + ".zip").getBytes("GB2312"), "ISO-8859-1"));
            response.setContentType("application/zip;charset=utf-8");
            response.setCharacterEncoding("UTF-8");

            // 输出流直接用ZipOutputStream包裹，这样直接输出压缩后的流。减少服务器生成压缩文件步骤。
            ZipOutputStream zipOutputStream = new ZipOutputStream(response.getOutputStream());

            for(String file : fileUrl){
                ZipEntry zipEntryXtv = new ZipEntry(file.substring(file.lastIndexOf("/")+1));
                File file1 = new File("/data/zywork-app-data/" + file);
                InputStream fis = new BufferedInputStream(new FileInputStream(file1));
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                zipOutputStream.putNextEntry(zipEntryXtv);
                zipOutputStream.write(buffer);
            }
            zipOutputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @PostMapping("admin/save")
    @SysLog(description = "后台保存GraphicOrderVO")
    public ResponseStatusVO save(@RequestBody @Validated GraphicOrderVO graphicOrderVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        graphicOrderService.save(BeanUtils.copy(graphicOrderVO, GraphicOrderDTO.class));
        return ResponseStatusVO.ok("添加成功", null);
    }

    @PostMapping("admin/batch-save")
    @SysLog(description = "后台批量保存GraphicOrderVO")
    public ResponseStatusVO saveBatch(@RequestBody @Validated List<GraphicOrderVO> graphicOrderVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        graphicOrderService.saveBatch(BeanUtils.copyListObj(graphicOrderVOList, GraphicOrderDTO.class));
        return ResponseStatusVO.ok("批量添加成功", null);
    }

    @GetMapping("admin/remove/{id}")
    @SysLog(description = "后台删除GraphicOrderVO")
    public ResponseStatusVO removeById(@PathVariable("id") Long id) {
        graphicOrderService.removeById(id);
        return ResponseStatusVO.ok("删除成功", null);
    }

    @PostMapping("admin/batch-remove")
    @SysLog(description = "后台批量删除GraphicOrderVO")
    public ResponseStatusVO removeByIds(@RequestBody String[] ids) {
        graphicOrderService.removeByIds(StringUtils.strArrayToLongArray(ids));
        return ResponseStatusVO.ok("批量删除成功", null);
    }

    @PostMapping("admin/update")
    @SysLog(description = "后台更新GraphicOrderVO")
    public ResponseStatusVO update(@RequestBody @Validated GraphicOrderVO graphicOrderVO, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        int updateRows = graphicOrderService.update(BeanUtils.copy(graphicOrderVO, GraphicOrderDTO.class));
        if (updateRows == 1) {
            return ResponseStatusVO.ok("更新成功", null);
        } else {
            return ResponseStatusVO.dataError("数据版本号有问题，在此更新前数据已被更新", null);
        }
    }

    @PostMapping("admin/batch-update")
    @SysLog(description = "后台批量更新GraphicOrderVO")
    public ResponseStatusVO updateBatch(@RequestBody @Validated List<GraphicOrderVO> graphicOrderVOList, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return ResponseStatusVO.dataError(BindingResultUtils.errorString(bindingResult), null);
        }
        graphicOrderService.updateBatch(BeanUtils.copyListObj(graphicOrderVOList, GraphicOrderDTO.class));
        return ResponseStatusVO.ok("批量更新成功", null);
    }

    @PostMapping("admin/active")
    @SysLog(description = "后台激活或冻结GraphicOrderVO")
    public ResponseStatusVO active(@RequestBody GraphicOrderVO graphicOrderVO) {
        graphicOrderService.update(BeanUtils.copy(graphicOrderVO, GraphicOrderDTO.class));
        return ResponseStatusVO.ok("激活或冻结成功", null);
    }

    @PostMapping("admin/batch-active")
    @SysLog(description = "后台批量激活或冻结GraphicOrderVO")
    public ResponseStatusVO activeBatch(@RequestBody @Validated List<GraphicOrderVO> graphicOrderVOList) {
        graphicOrderService.updateBatch(BeanUtils.copyListObj(graphicOrderVOList, GraphicOrderDTO.class));
        return ResponseStatusVO.ok("批量激活或冻结成功", null);
    }

    @GetMapping("admin/one/{id}")
    public ResponseStatusVO getById(@PathVariable("id") Long id) {
        GraphicOrderVO graphicOrderVO = new GraphicOrderVO();
        Object obj = graphicOrderService.getById(id);
        if (obj != null) {
            graphicOrderVO = BeanUtils.copy(obj, GraphicOrderVO.class);
        }
        return ResponseStatusVO.ok("查询成功", graphicOrderVO);
    }

    @GetMapping("admin/all")
    public ResponseStatusVO listAll() {
        PagerDTO pagerDTO = graphicOrderService.listAll();
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), GraphicOrderVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/all-cond")
    public ResponseStatusVO listAllByCondition(@RequestBody GraphicOrderQuery graphicOrderQuery) {
        PagerDTO pagerDTO = graphicOrderService.listAllByCondition(graphicOrderQuery);
        PagerVO pagerVO = BeanUtils.copy(pagerDTO, PagerVO.class);
        pagerVO.setRows(BeanUtils.copyList(pagerDTO.getRows(), GraphicOrderVO.class));
        return ResponseStatusVO.ok("查询成功", pagerVO);
    }

    @PostMapping("admin/pager-cond")
    public ResponseStatusVO listPageByCondition(@RequestBody GraphicOrderQuery graphicOrderQuery) {

        QueryWrapper queryWrapper = new QueryWrapper();

        long userId = SecurityUtils.getJwtUser().getUserId();

        List<GraphicExtDO> user_id = graphicExtService.list(new QueryWrapper<GraphicExtDO>().eq("user_id", userId));

        // 图文店
        if(user_id.size() > 0){
            List<Integer> ids;
            ids = user_id.stream().map(e->e.getId()).collect(Collectors.toList());
            queryWrapper.in("graphic_id",ids);
        }

        IPage page = graphicOrderExtService.page(new Page<>(graphicOrderQuery.getPageNo(), graphicOrderQuery.getPageSize()),queryWrapper);

        PagerDTO pagerDTO = new PagerDTO();
        pagerDTO.setTotal(page.getTotal());
        pagerDTO.setRows(page.getRecords());

        pagerDTO.setRows(pagerDTO.getRows().stream().map(e->{
            GraphicOrderExtDO graphicOrderExtDO = (GraphicOrderExtDO) e;
            GraphicOrderDTO graphicOrderDTO =  new GraphicOrderDTO();
            org.springframework.beans.BeanUtils.copyProperties(graphicOrderExtDO,graphicOrderDTO);
            // 图文店名称
            graphicOrderDTO.setGraphicValue(graphicExtService.getById(graphicOrderExtDO.getGraphicId()).getTwdmc());
            // 订单状态
            graphicOrderDTO.setPayStatusValue(PayStatusEnum.byCode(graphicOrderExtDO.getPayStatus()));
            return graphicOrderDTO;
        }).collect(Collectors.toList()));


        return ResponseStatusVO.ok("查询成功", pagerDTO);
    }

    @Autowired
    public void setGraphicOrderService(GraphicOrderService graphicOrderService) {
        this.graphicOrderService = graphicOrderService;
    }

}
